package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.bean.Dish;
import com.itheima.bean.DishFlavor;
import com.itheima.bean.OrderDetail;
import com.itheima.dao.DishDao;
import com.itheima.dto.DishDto;
import com.itheima.exception.CustomException;
import com.itheima.service.CategoryService;
import com.itheima.service.DishFlavorService;
import com.itheima.service.DishService;
import com.itheima.service.OrderDetailService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Tang
 * @date 2023/1/7
 */
@Service
public class DishServiceImpl extends ServiceImpl<DishDao, Dish> implements DishService {

    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
//    @Lazy  //使用懒加载解决循环依赖
    private CategoryService categoryService;


    /**
     * 新增菜品包含口味信息
     *
     * @param dishDto
     */
    @Override
    public void addDishWithFlavor(DishDto dishDto) {
        //优化：新增之前查询当前菜品名称是否存在
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Dish::getName, dishDto.getName());
        int count = this.count(wrapper);
        if (count > 0) {
            throw new CustomException("该菜品名称【" + dishDto.getName() + "】已存在！");
        }

        //0.开启事务
        //1.调用自身的新增方法，保存菜品的基本信息到dish表中
        this.save(dishDto);
        //2.调用dishFlavorService的接口，保存菜品口味信息到dish_flavor表中
        List<DishFlavor> flavors = dishDto.getFlavors();
        for (DishFlavor flavor : flavors) {
            //2.1 口味信息需要关联dish_id
            flavor.setDishId(dishDto.getId());
            //dishFlavorService.save(flavor);
        }
        dishFlavorService.saveBatch(flavors);
    }

    /**
     * 查询菜品信息以及口味
     *
     * @param id
     * @return
     */
    @Override
    public DishDto getDishWithFlavor(Long id) {
        //0.先创建出DishDto对象，用来封装返回数据
        DishDto dishDto = new DishDto();

        //1.查询dish表，将菜品基本信息查询出来，封装到dishDto
        Dish dish = this.getById(id);
        BeanUtils.copyProperties(dish, dishDto);

        //2.查询dish_flavor，根据菜品id将口味信息列表查询出来，封装到dishDto
        LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DishFlavor::getDishId, id);
        List<DishFlavor> flavors = dishFlavorService.list(wrapper);
        dishDto.setFlavors(flavors);

        //3.返回DishDto对象
        return dishDto;
    }

    /**
     * 更新菜品信息包括口味信息
     *
     * @param dishDto
     */
    @Override
    public void updateWithFlavor(DishDto dishDto) {
        //优化：
        //0.开启事务
        //1.根据菜品名称查询数据库dish表，校验菜品名称是否存在
        //1.1 构造查询条件，根据菜品名称去查
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Dish::getName, dishDto.getName());

        //1.2 排除自身，根据菜品id
        wrapper.ne(Dish::getId, dishDto.getId());

        //1.3 调用service统计方法，判断是否有数据
        int count = this.count(wrapper);
        if (count > 0) {
            throw new CustomException("该菜品名称【" + dishDto.getName() + "】已存在！");
        }

        //2.更新菜品信息数据到dish表
        this.updateById(dishDto);

        //3.保存口味信息数据到dish_flavor，关联菜品id
        //3.1 口味信息有可能是新增、删除、更新，更新口味信息之前全部删除原来的口味信息
        LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishFlavorLambdaQueryWrapper.eq(DishFlavor::getDishId, dishDto.getId());
        dishFlavorService.remove(dishFlavorLambdaQueryWrapper);
        //3.2 循环变量前端传递过来的口味信息数据，并且关联菜品id
        List<DishFlavor> flavors = dishDto.getFlavors();
        for (DishFlavor flavor : flavors) {
            //需要将id先置空 （使用到了逻辑删除需要做的操作）
            flavor.setId(null);
            flavor.setDishId(dishDto.getId());
            //dishFlavorService.save(flavor);
        }
        //3.3 批量保存口味数据
        dishFlavorService.saveBatch(flavors);
    }

    /**
     * 查询菜品列表包含口味信息
     *
     * @param dish
     * @return
     */
    @Override
    public List<DishDto> listWithFlavors(Dish dish) {
        //1.设置查询条件：分类id、菜品名称、菜品状态
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());
        wrapper.like(dish.getName() != null, Dish::getName, dish.getName());
        wrapper.eq(dish.getStatus() != null, Dish::getStatus, dish.getStatus());

        //2.调用父接口的查询方法，得到的List<Dish>
        List<Dish> dishList = this.list(wrapper);

        //3.封装List<DishDto>数据
        List<DishDto> dishDtoList = new ArrayList<>();
        //4.循环遍历List<Dish>
        for (Dish d : dishList) {
            //5.根据dish对象去封装DishDto
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(d, dishDto);

            //6.根据dishId去查口味表，将口味信息封装到DishDto
            LambdaQueryWrapper<DishFlavor> flavorWrapper = new LambdaQueryWrapper<>();
            flavorWrapper.eq(DishFlavor::getDishId, d.getId());
            List<DishFlavor> flavors = dishFlavorService.list(flavorWrapper);
            dishDto.setFlavors(flavors);

            //获取套餐的销售数量
            LambdaQueryWrapper<OrderDetail> olqw = new LambdaQueryWrapper<>();
            olqw.eq(OrderDetail::getDishId,d.getId());
            int count = orderDetailService.count(olqw);
            dishDto.setSaleNum(count);


            //7.将dishDto添加到List<DishDto>
            dishDtoList.add(dishDto);
        }

        //8.返回List<DishDto>给controller
        return dishDtoList;
    }

    /**
     * 批量删除菜品
     *
     * @param ids
     */
    @Override
    public void delete(String ids) {
        String[] split = ids.split(",");
        for (String s : split) {
            this.removeById(s);
        }
    }

    /**
     * 起售停售菜品
     *
     * @param status
     * @param ids    菜品ids
     * @return
     */
    @Override
    public void status(int status, String ids) {
        String[] idss = ids.split(",");
        for (String id : idss) {
            Dish dish = this.getById(id);
            dish.setStatus(status);
            this.updateById(dish);
        }
    }


}
